home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / mus / play / tracker_3_19.lzh / tracker / ss10_audio.c < prev    next >
C/C++ Source or Header  |  1993-11-18  |  6KB  |  282 lines

  1. /* ss10_audio.h */
  2.  
  3. /* $Id: ss10_audio.c,v 3.11 1993/11/17 15:31:16 espie Exp espie $
  4.  * $Log: ss10_audio.c,v $
  5.  * Revision 3.11  1993/11/17  15:31:16  espie
  6.  * *** empty log message ***
  7.  *
  8.  *
  9.  * Revision 3.9  1993/07/14  16:33:41  espie
  10.  * Fixed /16 bug.
  11.  *
  12.  * Revision 3.8  1993/05/09  14:06:03  espie
  13.  * Corrected mix problem.
  14.  *
  15.  * Revision 3.6  1992/12/03  15:00:50  espie
  16.  * restore stty.
  17.  *
  18.  * Revision 3.4  1992/11/24  10:51:19  espie
  19.  * Sync pseudo call.
  20.  *
  21.  * Revision 3.3  1992/11/22  17:20:01  espie
  22.  * Added update_frequency call, mostly unchecked
  23.  *
  24.  * Revision 3.2  1992/11/20  14:53:32  espie
  25.  * Added finetune.
  26.  *
  27.  * Revision 3.1  1992/11/19  20:44:47  espie
  28.  * Protracker commands.
  29.  *
  30.  * Revision 3.0  1992/11/18  16:08:05  espie
  31.  * New release.
  32.  *
  33.  * Revision 1.3  1992/11/17  15:38:00  espie
  34.  * discard_buffer() call for snappier interface calls.
  35.  * - Unified support for all sparcs.
  36.  * - moved down to level 2 io.
  37.  */
  38.  
  39. #include <stdio.h>
  40. #include "defs.h"
  41. #include "extern.h"
  42. #include <sun/audioio.h>
  43. #include <sys/ioctl.h>
  44. #include <fcntl.h>
  45. #include <stropts.h>
  46. #include <malloc.h>
  47.      
  48. /* things that aren't defined in all sun/audioio.h */
  49.  
  50. #ifndef AUDIO_ENCODING_LINEAR
  51. #define AUDIO_ENCODING_LINEAR (3)
  52. #endif
  53. #ifndef AUDIO_GETDEV
  54. #define AUDIO_GETDEV    _IOR(A, 4, int)
  55. #endif
  56. #ifndef AUDIO_DEV_UNKNOWN
  57. #define AUDIO_DEV_UNKNOWN (0)
  58. #endif
  59. #ifndef AUDIO_DEV_AMD
  60. #define AUDIO_DEV_AMD (1)
  61. #endif
  62.  
  63. LOCAL char *id = "$Id: ss10_audio.c,v 3.11 1993/11/17 15:31:16 espie Exp espie $";
  64.  
  65. LOCAL int audio;
  66.  
  67. LOCAL struct audio_info info;
  68. LOCAL char *buffer;
  69. LOCAL short *sbuffer;
  70. LOCAL int index;
  71. LOCAL int dsize;
  72.  
  73. LOCAL int stereo;
  74. LOCAL int primary, secondary;
  75.  
  76. void set_mix(percent)
  77. int percent;
  78.     {
  79.     percent *= 256;
  80.     percent /= 100;
  81.     primary = percent;
  82.     secondary = 512 - percent;
  83.     }
  84.  
  85. #define abs(x) ((x) < 0 ? -(x) : (x))
  86.  
  87. LOCAL int available(f)
  88. int f;
  89.     {
  90.     static int possible[] = { 8000, 9600, 11025, 16000, 18900, 22050, 32000,
  91.         37800, 44100, 48000, 0};
  92.     int best = 0;
  93.     int i;
  94.  
  95.     for (i = 0; possible[i]; i++)
  96.         if (abs(possible[i] - f) < abs(best - f))
  97.             best = possible[i];
  98.     return best;
  99.     }
  100.  
  101. int open_audio(f, s)
  102. int f;
  103. int s;
  104.     {
  105.     int type;
  106.  
  107.     audio = open("/dev/audio", O_WRONLY|O_NDELAY);
  108.     if (audio == -1)
  109.         {
  110.         fprintf(stderr, "Error: could not open audio\n");
  111.         end_all();
  112.         }
  113.     if (f == 0)
  114.         f = 22050;
  115.         /* round frequency to acceptable value */
  116.     f = available(f);
  117.  
  118.         /* check whether we know about AUDIO_ENCODING_LINEAR */
  119.     if (ioctl(audio, AUDIO_GETDEV, &type) ||
  120.     type == AUDIO_DEV_UNKNOWN || type == AUDIO_DEV_AMD)
  121.         {
  122.             /* not a ss 10 -> revert to base quality audio */
  123.         stereo = 0;
  124.         dsize = 1;
  125.         info.play.sample_rate = 8000;
  126.         info.play.encoding = AUDIO_ENCODING_ULAW;
  127.         info.play.channels = 1;
  128.         }
  129.     else
  130.         {
  131.             /* tentative set up */
  132.         stereo = s;
  133.         AUDIO_INITINFO(&info);
  134.         info.play.sample_rate = f;
  135.         info.play.precision = 16;
  136.         dsize = 2;
  137.         if (stereo)
  138.             {
  139.             info.play.channels = 2;
  140.             }
  141.         else
  142.             info.play.channels = 1;
  143.             /* try it */
  144.         info.play.encoding = AUDIO_ENCODING_LINEAR;
  145.         if (ioctl(audio, AUDIO_SETINFO, &info) != 0)
  146.             /* didn't work: fatal problem */
  147.             end_all();
  148.         }
  149.     index = 0;
  150.     buffer = (char *)malloc(dsize * info.play.channels * info.play.sample_rate);
  151.     sbuffer = (short *) buffer;
  152.     if (!buffer)
  153.         end_all();
  154.     return info.play.sample_rate;
  155.     }
  156.  
  157. void set_synchro(s)
  158. BOOL s;
  159.     {
  160.     }
  161.  
  162. int update_frequency()
  163.     {
  164.     int oldfreq;
  165.  
  166.     oldfreq = info.play.sample_rate;
  167.     if (ioctl(audio, AUDIO_GETINFO, &info) == 0)
  168.         {
  169.         if (oldfreq != info.play.sample_rate)
  170.             {
  171.             buffer = realloc(buffer, 
  172.                 dsize * info.play.channels * info.play.sample_rate);
  173.             sbuffer = (short *)buffer;
  174.             return info.play.sample_rate;
  175.             }
  176.         }
  177.     return 0;
  178.     }
  179.  
  180.  
  181. LOCAL int sign(x)
  182. unsigned char x;
  183.     {
  184.     return x;
  185.     }
  186.  
  187. /************************************************************************/
  188. /*      For routine 'cvt' only                                          */
  189. /************************************************************************/
  190. /*      Copyright 1989 by Rich Gopstein and Harris Corporation          */
  191. /************************************************************************/
  192.  
  193. LOCAL unsigned int cvt(ch)
  194. int ch;
  195.     {
  196.     int mask;
  197.  
  198.     if (ch < 0)
  199.         {
  200.         ch = -ch;
  201.         mask = 0x7f;
  202.         }
  203.     else
  204.         mask = 0xff;
  205.  
  206.     if (ch < 32)
  207.         {
  208.         ch = 0xF0 | 15 - (ch / 2);
  209.         }
  210.     else if (ch < 96)
  211.         {
  212.         ch = 0xE0 | 15 - (ch - 32) / 4;
  213.         }
  214.     else if (ch < 224)
  215.         {
  216.         ch = 0xD0 | 15 - (ch - 96) / 8;
  217.         }
  218.     else if (ch < 480)
  219.         {
  220.         ch = 0xC0 | 15 - (ch - 224) / 16;
  221.         }
  222.     else if (ch < 992)
  223.         {
  224.         ch = 0xB0 | 15 - (ch - 480) / 32;
  225.         }
  226.     else if (ch < 2016)
  227.         {
  228.         ch = 0xA0 | 15 - (ch - 992) / 64;
  229.         }
  230.     else if (ch < 4064)
  231.         {
  232.         ch = 0x90 | 15 - (ch - 2016) / 128;
  233.         }
  234.     else if (ch < 8160)
  235.         {
  236.         ch = 0x80 | 15 - (ch - 4064) /  256;
  237.         }
  238.     else
  239.         {
  240.         ch = 0x80;
  241.         }
  242.     return (mask & ch);
  243.     }
  244.  
  245.  
  246. void output_samples(left, right)
  247. int left, right;
  248.     {
  249.     if (stereo)
  250.         {
  251.         sbuffer[index++] = (left * primary + right * secondary)/256;
  252.         sbuffer[index++] = (right * primary + left * secondary)/256;
  253.         }
  254.     else
  255.         switch(info.play.encoding)
  256.             {
  257.         case AUDIO_ENCODING_LINEAR:
  258.             sbuffer[index++] = left + right;
  259.             break;
  260.         case AUDIO_ENCODING_ULAW:
  261.             buffer[index++] = cvt((left + right) /4);
  262.             break;
  263.             }
  264.     }
  265.  
  266. void flush_buffer()
  267.     {
  268.     write(audio, buffer, dsize * index);
  269.     index = 0;
  270.     }
  271.  
  272. void discard_buffer()
  273.     {
  274.     ioctl(audio, I_FLUSH, FLUSHW);
  275.     }
  276.  
  277. void close_audio()
  278.     {
  279.     free(buffer);
  280.     close(audio);
  281.     }
  282.